#!/usr/bin/env python3
# -*- coding: utf-8 -*-

""" 孙悟空 """

__auther__ = 'igofishing'


import numpy as np


DNA_size = 10   # dna 长度
train_num = 3     # 样本数量
train_times = 1000    # 单次训练次数

# 求解参数的空间
PARA_size = 3   # 参数的数量
PARA_data = [2, 2, 2]    # 设定参数
interval_val = [0, 10]      # 随机参数的范围
interval_xy = [0, 10]       # 随机变量空间


def source(ant_one, test_one):
    """ 需要测量的函数 """
    return ant_one[0]*test_one[0] + ant_one[1]*test_one[1] + ant_one[2]


def get_pop():
    """ 获取初始化群体 """
    return np.random.randint(2, size=(train_num*PARA_size, DNA_size))


def translate(pop):
    """ 翻译二进制到实数 """
    interval_len = interval_val[1] - interval_val[0]
    return pop.dot(2 ** np.arange(DNA_size)[::-1]) / float(2 ** DNA_size - 1) * interval_len + interval_val[0]


def select(ants):
    """ 进行样本评测 """
    mistake_array = np.zeros((train_num,))
    # print(mistake_array)
    for cell in range(train_times):
        sample = np.random.rand(train_num*(PARA_size-1)).reshape(train_num, (PARA_size-1))
        sample = sample * interval_xy[1] - interval_xy[1]/2
        add_array = np.ones((train_num, 1))
        sample = np.hstack((sample, add_array))
        # sample[2] = 1

        # 计算基因曲线数据
        res = np.multiply(ants, sample)
        # print(ants)
        # print(sample)
        genes_data = np.sum(res, axis=1)
        # print('基因数据', genes_data)

        # 计算出真实曲线的数据
        real_para = np.array(PARA_data*train_num).reshape(train_num, PARA_size)
        real_val = np.multiply(real_para, sample)

        # real_res = source(ants, sample)
        # print(real_para)
        # print(sample)
        real_data = np.sum(real_val, axis=1)
        # print('真实数据', real_data)

        # 计算误差
        mistake = np.abs(np.subtract(real_data, genes_data))
        # mistake = (1/(mistake+0.001) * 10000)
        mistake = 1/(mistake+0.001) * 100

        # 累计误差
        mistake_array = np.add(mistake_array, mistake)
        # print('总误差', mistake_array)
    return mistake_array


def select_yes(pop, mistakes):
    """ 根据父代适应度挑选出优秀群体 """
    next_over = np.random.choice(np.arange(train_num), size=train_num, replace=True,
                                 p=mistakes/np.sum(mistakes))
    print(pop[next_over])
    return pop[next_over]


def crossover(next_over, pop_past):
    """ 使用优秀个体产生新一代群体 """
    # pop_past = np.random.shuffle(pop_past)
    print('pop_past', pop_past)
    for cell in range(PARA_size):
        itd = np.random.randint(DNA_size)
        # next_over[cell] = next_over[cell][0:itd] + pop_past[cell][itd:]
        # print('erbian', next_over[cell][0:itd])
        # print('erbian', pop_past[cell])

    print(next_over)
    return next_over


if __name__ == '__main__':
    pop = get_pop()
    ants = translate(pop).reshape(train_num, PARA_size)
    print(ants)
    mistakes = select(ants)
    print(mistakes)
    yes_ants = select_yes(pop, mistakes)
    next_pop = crossover(yes_ants, pop)


